﻿namespace NTLib.Pipe.Streaming.Formats
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using NTLib.Core.Memory;
    using NTLib.Core.Attributes;
    using NTLib.Core.Reflection;
    using System.Runtime.Serialization.Json;
    using System.IO;
    using Core.Component;
    using Formats;

    /// <summary>
    /// Implement only the data convertion not the protocol.
    /// To access a simple protocol use SimpleJsonFormatter
    /// </summary>
    public abstract class JsonPackageFormater : BaseConcurentPackageFormater, IPackageFormater
    {
        #region Fields
        #endregion

        #region Ctor

        /// <summary>
        /// Prevents a default instance of the <see cref="JsonPackageFormater"/> class from being created.
        /// </summary>
        public JsonPackageFormater()
        {
        }

        #endregion

        #region Methods

        /// <summary>
        /// Converts the data to bytes.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="T"></param>
        /// <returns></returns>
        protected override object ConvertBytesToData(Stream data, Type T)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(T);

            return serializer.ReadObject(data);
        }

        /// <summary>
        /// Converts the data to bytes.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="T"></param>
        /// <returns></returns>
        protected override byte[] ConvertDataToBytes(object data, Type T)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(T);

            using (MemoryStream stream = new MemoryStream())
            {
                serializer.WriteObject(stream, data);
                stream.Seek(0, SeekOrigin.Begin);

                byte[] result = new byte[stream.Length];
                stream.Read(result, 0, (int)stream.Length);

                return result;
            }
        }

        #endregion
    }
}
